{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[B1P475]\n",
    "- def 是可执行的代码，在 Python 运行 def 之前，函数并不存在。def 创建了一个对象，并将其赋值给了某一变量名，函数名变成了一个函数对象的引用。\n",
    "    由于 def 是一个语句，所以可以出现在任何地方，不如敲套在 while 中，或者在 def 中嵌套 def.\n",
    "    如："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "if True:\n",
    "    def func():\n",
    "        ...\n",
    "else:\n",
    "    def func():\n",
    "        ...\n",
    "    \n",
    "# 函数是运行时才被定义的，函数名并没后什么特别之处，关键在于函数名所引起的那个对象。[B1P477]\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 多态\n",
    "```python\n",
    "def times(x, y):\n",
    "    return x * y\n",
    "# times 函数中表达式 x * y 的意义完全取决于 x 和 y 的对象类型，\n",
    "# 同样的函数，在一种对象下执行的是乘法(3 * 3)，在另一种对象下执行的确实重复（‘a’ * 3）\n",
    "# Python 把对某一对象在某种语法下的合理性交给那个对象自身来判断，* 作为一个分派机制，将执行的控制权移交给被处理的对象。\n",
    "# 这种依赖类型的行为称为多态。其含义就是一个操作的意义取决于被操作对象的类型。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 工厂函数（闭包）[P501]\n",
    "这种函数对象能够记忆外层作用域里的值，不管那些嵌套作用是否还在内存中存在。\n",
    "```python\n",
    "def maker(N):\n",
    "    def action(X):\n",
    "        return X ** N\n",
    "    return action\n",
    "```\n",
    "定义一个外层函数，返回一个嵌套函数，却并不调用内嵌函数。maker创造出action,却只是简单地返回action而不执行它。若调用外部函数，我们得到的只是内嵌函数的一个引用。\n",
    "```python\n",
    "f = maker(2)\n",
    "f(3) # 9\n",
    "f(4) # 16\n",
    "```\n",
    "\n",
    "内嵌函数记住了 N = 2,即maker内部的变量N。实际上，在外层嵌套局部作用域内的N被作为执行状态信息保留了下来，并附加到生成的 action 函数上。\n",
    "如果再调用外部函数，可以得到一个新的不同状态信息的嵌套函数。\n",
    "```python\n",
    "g = maker(3) # 返回的action函数用来求一个数的立方\n",
    "g(4) # 64\n",
    "f(4) # 16\n",
    "```\n",
    "每次对工厂函数的调用，都将得到属于调用自己的状态信息的集合。我们使 g 函数记住了 N = 3，使 f 函数记住了 N = 2。每个函数都有自己的状态值，这个之态信息由 maker 中的变量 N 决定。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 匿名函数 lambda[P565]\n",
    "lambda 是为编写简单函数而设计的，而 def 能处理更大的任务。lambda 主题结构中只能封装有限的逻辑，连 if 这样的语句都不能使用。\n",
    "```python\n",
    "f = lambda x, y, z:x + y + z\n",
    "f(2, 3, 4) # 9\n",
    "```\n",
    "lambda 也支持默认参数\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "14"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f = lambda x = 1, y = 2, z = 3:x + y + z\n",
    "f() # 6\n",
    "f(9) # 9 + 2 + 3 = 14"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 在可迭代对象上映射函数:map\n",
    "map 是内置函数，在一些使用模式下它比自己手工编写的 for 更快。给定多个序列参数，map 会按照顺序，并行地从各个序列中逐项取出一组又一组参数，然后传入函数中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[11, 12, 13, 14, 15]\n",
      "[13, 16, 19, 22, 25]\n"
     ]
    }
   ],
   "source": [
    "def f1(x):\n",
    "    return x + 10\n",
    "\n",
    "def f2(x, y):\n",
    "    return x + 2 * y\n",
    "\n",
    "L1 = [1, 2, 3, 4, 5]\n",
    "L2 = [6, 7, 8, 9, 10]\n",
    "\n",
    "print(list(map(f1, L1)))\n",
    "print(list(map(f2, L1, L2)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### filter 与 reduce 以后再补充。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
